package com.wh.hotel.service.strategy.room;

import com.google.common.collect.Lists;
import com.wh.hotel.dao.HotelRoomTypeRelationDao;
import com.wh.hotel.model.HotelRoomTypeRelation;
import com.wh.hotel.param.HotelQueryRoomParam;
import com.wh.hotel.po.StrategySuitRangePo;
import com.wh.hotel.po.SuitHotelRoomPo;
import com.wh.hotel.vo.HotelPriceStrategyVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author luweije
 */
@Slf4j
@Component
public class RoomTypeSuitRange extends SuitRangeAbstract {

    @Resource
    private HotelRoomTypeRelationDao hotelRoomTypeRelationDao;

    @Override
    public boolean isHit(HotelQueryRoomParam param, HotelPriceStrategyVo strategyVo) {
        StrategySuitRangePo suitRangePo = strategyVo.getSuitRangePo();
        for (SuitHotelRoomPo suitHotelRoomPo : suitRangePo.getSuitHotelRoomPoList()) {
            if (!Objects.equals(suitHotelRoomPo.getHotelId(), param.getHotelId())) {
                continue;
            }
            if (CollectionUtils.isEmpty(suitHotelRoomPo.getRoomTypeIdList())) {
                return true;
            }
            if (suitHotelRoomPo.getRoomTypeIdList().contains(param.getRoomTypeId())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<SuitHotelRoomPo> calculateRoomSuitRange(HotelPriceStrategyVo strategyVo) {
        StrategySuitRangePo suitRangePo = strategyVo.getSuitRangePo();
        List<SuitHotelRoomPo> suitHotelRoomPoList = suitRangePo.getSuitHotelRoomPoList();
        List<Long> hotelIdList = suitHotelRoomPoList.stream()
                .filter(po -> CollectionUtils.isEmpty(po.getRoomTypeIdList()))
                .map(SuitHotelRoomPo::getHotelId)
                .collect(Collectors.toList());
        Map<Long, List<Long>> hotelRoomTypeMap = hotelRoomTypeRelationDao.selectByHotelIdList(hotelIdList)
                .stream()
                .collect(Collectors.groupingBy(HotelRoomTypeRelation::getHotelId, Collectors.mapping(HotelRoomTypeRelation::getRoomTypeId, Collectors.toList())));
        List<SuitHotelRoomPo> result = Lists.newArrayList();
        for (SuitHotelRoomPo suitHotelRoomPo : suitHotelRoomPoList) {
            if (CollectionUtils.isNotEmpty(suitHotelRoomPo.getRoomTypeIdList())) {
                result.add(suitHotelRoomPo);
                continue;
            }
            List<Long> roomTypeIdList = hotelRoomTypeMap.get(suitHotelRoomPo.getHotelId());
            if (CollectionUtils.isEmpty(roomTypeIdList)) {
                continue;
            }
            SuitHotelRoomPo cpRoomPo = new SuitHotelRoomPo();
            cpRoomPo.setHotelId(suitHotelRoomPo.getHotelId());
            cpRoomPo.setRoomTypeIdList(roomTypeIdList);
            result.add(cpRoomPo);
        }
        return result;
    }
}
